package org.light.generator;

import org.light.domain.Statement;
import org.light.domain.StatementList;
import org.light.domain.Util;

public class PDFUtilGenerator extends Util{
	public PDFUtilGenerator(){
		super();
		super.fileName = "PDFUtil.go";
	}
	
	public PDFUtilGenerator(String packageToken){
		super();
		this.setPackageToken(packageToken);
		super.fileName = "PDFUtil.go";
	}
	
	@Override
	public void setPackageToken(String packageToken) {
		this.packageToken = packageToken;
	}
	
	@Override
	public String generateUtilString() {
		StatementList sList = new StatementList();
		sList.add(new Statement(1000L,0,"package utils"));
		sList.add(new Statement(2000L,0,""));
		sList.add(new Statement(3000L,0,"import ("));
		sList.add(new Statement(4000L,1,"\"bytes\""));
		sList.add(new Statement(5000L,1,"\"image\""));
		sList.add(new Statement(6000L,1,"\"image/draw\""));
		sList.add(new Statement(7000L,1,"\"image/png\""));
		sList.add(new Statement(8000L,1,"\"math\""));
		sList.add(new Statement(9000L,1,"\"os\""));
		sList.add(new Statement(10000L,1,"\"strconv\""));
		sList.add(new Statement(11000L,0,""));
		sList.add(new Statement(12000L,1,"\"github.com/jung-kurt/gofpdf\""));
		sList.add(new Statement(13000L,0,")"));
		sList.add(new Statement(14000L,0,""));
		sList.add(new Statement(15000L,0,"var ("));
		sList.add(new Statement(16000L,1,"colCount = 6"));
		sList.add(new Statement(17000L,1,"colWd    = float64(180) / float64(colCount)"));
		sList.add(new Statement(18000L,1,"marginH  = 15.0"));
		sList.add(new Statement(19000L,1,"lineHt   = 5.5"));
		sList.add(new Statement(20000L,1,"cellGap  = 2.0"));
		sList.add(new Statement(21000L,0,")"));
		sList.add(new Statement(22000L,0,""));
		sList.add(new Statement(23000L,0,"type cellType struct {"));
		sList.add(new Statement(24000L,1,"str  string"));
		sList.add(new Statement(25000L,1,"list [][]byte"));
		sList.add(new Statement(26000L,1,"ht   float64"));
		sList.add(new Statement(27000L,0,"}"));
		sList.add(new Statement(28000L,0,""));
		sList.add(new Statement(29000L,0,"var ("));
		sList.add(new Statement(30000L,1,"cellList []cellType"));
		sList.add(new Statement(31000L,1,"cell     cellType"));
		sList.add(new Statement(32000L,0,")"));
		sList.add(new Statement(33000L,0,""));
		sList.add(new Statement(34000L,0,"// GeneratePdf generates our pdf by adding text and images to the page"));
		sList.add(new Statement(35000L,0,"// then saving it to a file (name specified in params)."));
		sList.add(new Statement(36000L,0,"func GeneratePdf(filename string) error {"));
		sList.add(new Statement(37000L,1,"pdf := gofpdf.New(\"P\", \"mm\", \"A4\", \"\")"));
		sList.add(new Statement(38000L,1,"pdf.AddPage()"));
		sList.add(new Statement(39000L,1,"pdf.AddUTF8Font(\"Microsoft Yahei\", \"\", \"msyh.ttf\")"));
		sList.add(new Statement(40000L,1,"pdf.SetFont(\"Microsoft Yahei\", \"B\", 16)"));
		sList.add(new Statement(41000L,1,"// CellFormat(width, height, text, border, position after, align, fill, link, linkStr)"));
		sList.add(new Statement(42000L,1,"pdf.CellFormat(190, 7, \"Welcome to topgoer.com\", \"0\", 0, \"CM\", false, 0, \"\")"));
		sList.add(new Statement(43000L,1,"// ImageOptions(src, x, y, width, height, flow, options, link, linkStr)"));
		sList.add(new Statement(44000L,1,"pdf.ImageOptions(\"topgoer.png\", 80, 20, 0, 0, false,"));
		sList.add(new Statement(45000L,2,"gofpdf.ImageOptions{ImageType: \"PNG\", ReadDpi: true}, 0, \"\")"));
		sList.add(new Statement(46000L,1,"return pdf.OutputFileAndClose(filename)"));
		sList.add(new Statement(47000L,0,"}"));
		sList.add(new Statement(48000L,0,""));
		sList.add(new Statement(49000L,0,"func ExportPDFWithImage(sheetName string, headers []string,"));
		sList.add(new Statement(50000L,1,"contents [][]interface{}, isImages []bool) *gofpdf.Fpdf {"));
		sList.add(new Statement(51000L,1,"containsImage := ContainsImage(isImages)"));
		sList.add(new Statement(52000L,1,"colCount = len(headers)"));
		sList.add(new Statement(53000L,1,"colWd = float64(180) / float64(colCount)"));
		sList.add(new Statement(54000L,1,"rowsPageContains := 16"));
		sList.add(new Statement(55000L,0,""));
		sList.add(new Statement(56000L,1,"if containsImage {"));
		sList.add(new Statement(57000L,2,"colWd = float64(270) / float64(colCount)"));
		sList.add(new Statement(58000L,1,"}"));
		sList.add(new Statement(59000L,0,""));
		sList.add(new Statement(60000L,1,"pdf := gofpdf.New(\"P\", \"mm\", \"A4\", \"\") // 210 x 297"));
		sList.add(new Statement(61000L,1,"if containsImage {"));
		sList.add(new Statement(62000L,2,"lineHt = 16.5"));
		sList.add(new Statement(63000L,2,"pdf = gofpdf.New(\"L\", \"mm\", \"A4\", \"\") // 210 x 297"));
		sList.add(new Statement(64000L,2,"rowsPageContains = int(float64(180)/lineHt) - 2"));
		sList.add(new Statement(65000L,1,"}"));
		sList.add(new Statement(66000L,0,""));
		sList.add(new Statement(67000L,1,"cellList = make([]cellType, colCount)"));
		sList.add(new Statement(68000L,0,""));
		sList.add(new Statement(69000L,1,"pdf.SetMargins(marginH, 15, marginH)"));
		sList.add(new Statement(70000L,1,"pdf.AddUTF8Font(\"Microsoft Yahei\", \"\", \"msyh.ttf\")"));
		sList.add(new Statement(71000L,1,"pdf.SetFont(\"Microsoft Yahei\", \"\", 14)"));
		sList.add(new Statement(72000L,1,"//pdf.SetFont(\"NotoSansSC\", \"\", 14)"));
		sList.add(new Statement(73000L,1,"for i := 0; i < int(math.Ceil(float64(len(contents))/float64(rowsPageContains))); i++ {"));
		sList.add(new Statement(74000L,2,"endFlag := i*rowsPageContains + rowsPageContains"));
		sList.add(new Statement(75000L,2,"if endFlag > len(contents) {"));
		sList.add(new Statement(76000L,3,"endFlag = len(contents)"));
		sList.add(new Statement(77000L,2,"}"));
		sList.add(new Statement(78000L,2,"pageContents := contents[i*rowsPageContains : endFlag]"));
		sList.add(new Statement(79000L,2,"addPDFPageWithImage(pdf, sheetName, headers, pageContents, isImages)"));
		sList.add(new Statement(80000L,1,"}"));
		sList.add(new Statement(81000L,0,""));
		sList.add(new Statement(82000L,1,"// if err := pdf.OutputFileAndClose(\"1.pdf\"); err != nil {"));
		sList.add(new Statement(83000L,1,"// 	panic(err.Error())"));
		sList.add(new Statement(84000L,1,"// }"));
		sList.add(new Statement(85000L,1,"return pdf"));
		sList.add(new Statement(86000L,0,"}"));
		sList.add(new Statement(87000L,0,""));
		sList.add(new Statement(88000L,0,"func addPDFPageWithImage(pdf *gofpdf.Fpdf, sheetName string, headers []string,"));
		sList.add(new Statement(89000L,1,"contents [][]interface{}, isImages []bool) *gofpdf.Fpdf {"));
		sList.add(new Statement(90000L,1,"//alignList := []string{\"L\", \"C\", \"R\", \"L\", \"C\", \"R\"}"));
		sList.add(new Statement(91000L,1,"alignList := make([]string, colCount)"));
		sList.add(new Statement(92000L,1,"for i, _ := range alignList {"));
		sList.add(new Statement(93000L,2,"alignList[i] = \"C\""));
		sList.add(new Statement(94000L,1,"}"));
		sList.add(new Statement(95000L,0,""));
		sList.add(new Statement(96000L,1,"header := headers"));
		sList.add(new Statement(97000L,1,"pdf.AddPage()"));
		sList.add(new Statement(98000L,0,""));
		sList.add(new Statement(99000L,1,"//设置表格第一行的样式（也就是在设置 <thead> 标签的样式）"));
		sList.add(new Statement(100000L,1,"pdf.SetTextColor(224, 224, 224)"));
		sList.add(new Statement(101000L,1,"pdf.SetFillColor(64, 64, 64)"));
		sList.add(new Statement(102000L,1,"for colJ := 0; colJ < colCount; colJ++ {"));
		sList.add(new Statement(103000L,2,"pdf.CellFormat(colWd, 10, header[colJ], \"1\", 0, \"CM\", true, 0, \"\")"));
		sList.add(new Statement(104000L,1,"}"));
		sList.add(new Statement(105000L,1,"pdf.Ln(-1)"));
		sList.add(new Statement(106000L,0,""));
		sList.add(new Statement(107000L,1,"//设置每一行"));
		sList.add(new Statement(108000L,1,"pdf.SetTextColor(24, 24, 24)"));
		sList.add(new Statement(109000L,1,"pdf.SetFillColor(255, 255, 255)"));
		sList.add(new Statement(110000L,1,"y := pdf.GetY()"));
		sList.add(new Statement(111000L,1,"for rowJ := 0; rowJ < len(contents); rowJ++ {"));
		sList.add(new Statement(112000L,2,"maxHt := lineHt"));
		sList.add(new Statement(113000L,0,""));
		sList.add(new Statement(114000L,2,"//计算单元格的高度"));
		sList.add(new Statement(115000L,2,"for colJ := 0; colJ < colCount; colJ++ {"));
		sList.add(new Statement(116000L,3,"if !isImages[colJ] {"));
		sList.add(new Statement(117000L,4,"cell.str = contents[rowJ][colJ].(string)"));
		sList.add(new Statement(118000L,4,"rows := count6charsRows(cell.str)"));
		sList.add(new Statement(119000L,4,"cell.ht = float64(rows) * lineHt"));
		sList.add(new Statement(120000L,4,"if cell.ht > maxHt {"));
		sList.add(new Statement(121000L,5,"maxHt = cell.ht"));
		sList.add(new Statement(122000L,4,"}"));
		sList.add(new Statement(123000L,4,"cellList[colJ] = cell"));
		sList.add(new Statement(124000L,3,"} else {"));
		sList.add(new Statement(125000L,4,"rows := count6charsRows(cell.str)"));
		sList.add(new Statement(126000L,4,"cell.ht = float64(rows) * lineHt"));
		sList.add(new Statement(127000L,4,"if cell.ht > maxHt {"));
		sList.add(new Statement(128000L,5,"maxHt = cell.ht"));
		sList.add(new Statement(129000L,4,"}"));
		sList.add(new Statement(130000L,4,"cellList[colJ] = cell"));
		sList.add(new Statement(131000L,3,"}"));
		sList.add(new Statement(132000L,2,"}"));
		sList.add(new Statement(133000L,0,""));
		sList.add(new Statement(134000L,2,"//循环渲染每个单元格"));
		sList.add(new Statement(135000L,2,"x := marginH"));
		sList.add(new Statement(136000L,2,"for colJ := 0; colJ < colCount; colJ++ {"));
		sList.add(new Statement(137000L,3,"pdf.Rect(x, y, colWd, maxHt+cellGap*2, \"D\")"));
		sList.add(new Statement(138000L,3,"cell = cellList[colJ]"));
		sList.add(new Statement(139000L,3,"cellY := y + cellGap + (maxHt-cell.ht)/2"));
		sList.add(new Statement(140000L,3,"if !isImages[colJ] {"));
		sList.add(new Statement(141000L,4,"rows := count6charsRows(cell.str)"));
		sList.add(new Statement(142000L,4,"for splitJ := 0; splitJ < rows ; splitJ++ {"));
		sList.add(new Statement(143000L,5,"pdf.SetXY(x+cellGap, cellY)"));
		sList.add(new Statement(144000L,5,"rowContent :=  cut6chars(cell.str,splitJ)"));
		sList.add(new Statement(144100L,5,"if len(rowContent)>0 {"));
		sList.add(new Statement(145000L,6,"pdf.CellFormat(colWd-cellGap*2, lineHt, rowContent, \"\", 0, alignList[colJ], false, 0, \"\")"));
		sList.add(new Statement(146000L,6,"pdf.Ln(-1)"));
		sList.add(new Statement(146200L,5,"}"));
		sList.add(new Statement(147000L,5,"cellY += lineHt"));
		sList.add(new Statement(148000L,4,"}"));
		sList.add(new Statement(149000L,3,"} else {"));
		sList.add(new Statement(150000L,4,"bbb := bytes.NewBuffer(contents[rowJ][colJ].([]byte))"));
		sList.add(new Statement(151000L,4,"m, _, _ := image.Decode(bbb) // 图片文件解码]]"));
		sList.add(new Statement(152000L,4,"if m != nil {"));
		sList.add(new Statement(153000L,5,"rgbImg := imageToRGBA(m)"));
		sList.add(new Statement(154000L,5,"//subImg := rgbImg.SubImage(image.Rect(0, 0, 200, 50)) //图片裁剪x0 y0 x1 y1"));
		sList.add(new Statement(155000L,5,"fileName := \"temp\" + strconv.FormatInt(int64(rowJ), 10) + strconv.FormatInt(int64(colJ), 10) + \".png\""));
		sList.add(new Statement(156000L,0,""));
		sList.add(new Statement(157000L,5,"b := rgbImg.Bounds()"));
		sList.add(new Statement(158000L,5,"width := b.Max.X"));
		sList.add(new Statement(159000L,5,"height := b.Max.Y"));
		sList.add(new Statement(160000L,5,"ratio := float64(lineHt) / float64(height)"));
		sList.add(new Statement(161000L,5,"picWidth := float64(width) * ratio"));
		sList.add(new Statement(162000L,5,"picHeight :=  float64(height) * ratio"));
		sList.add(new Statement(163000L,0,""));
		sList.add(new Statement(164000L,5,"f, _ := os.Create(fileName) //创建文件"));
		sList.add(new Statement(165000L,0,""));
		sList.add(new Statement(166000L,5,"defer f.Close()       //关闭文件"));
		sList.add(new Statement(167000L,5,"png.Encode(f, rgbImg) //写入文件"));
		sList.add(new Statement(168000L,0,""));
		sList.add(new Statement(169000L,5,"pdf.ImageOptions(fileName, x+(colWd-picWidth)/2.0, cellY, picWidth, picHeight, false,"));
		sList.add(new Statement(170000L,6,"gofpdf.ImageOptions{ImageType: \"PNG\", ReadDpi: true}, 0, \"\")"));
		sList.add(new Statement(171000L,5,"defer os.Remove(fileName)"));
		sList.add(new Statement(172000L,4,"}"));
		sList.add(new Statement(173000L,3,"}"));
		sList.add(new Statement(174000L,3,"x += colWd"));
		sList.add(new Statement(175000L,2,"}"));
		sList.add(new Statement(176000L,2,"y += maxHt + cellGap*2"));
		sList.add(new Statement(177000L,1,"}"));
		sList.add(new Statement(178000L,1,"return pdf"));
		sList.add(new Statement(179000L,0,"}"));
		sList.add(new Statement(180000L,0,""));
		sList.add(new Statement(181000L,0,"func imageToRGBA(src image.Image) *image.RGBA {"));
		sList.add(new Statement(182000L,1,"// No conversion needed if image is an *image.RGBA."));
		sList.add(new Statement(183000L,1,"if dst, ok := src.(*image.RGBA); ok {"));
		sList.add(new Statement(184000L,2,"return dst"));
		sList.add(new Statement(185000L,1,"}"));
		sList.add(new Statement(186000L,0,""));
		sList.add(new Statement(187000L,1,"// Use the image/draw package to convert to *image.RGBA."));
		sList.add(new Statement(188000L,1,"b := src.Bounds()"));
		sList.add(new Statement(189000L,1,"dst := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))"));
		sList.add(new Statement(190000L,1,"draw.Draw(dst, dst.Bounds(), src, b.Min, draw.Src)"));
		sList.add(new Statement(191000L,1,"return dst"));
		sList.add(new Statement(192000L,0,"}"));
		sList.add(new Statement(193000L,0,""));
		sList.add(new Statement(194000L,0,"func substring(source string, start int, end int) string {"));
		sList.add(new Statement(195000L,1,"var r = []rune(source)"));
		sList.add(new Statement(196000L,1,"length := len(r)"));
		sList.add(new Statement(197000L,0,""));
		sList.add(new Statement(198000L,1,"if start < 0 || start > end {"));
		sList.add(new Statement(199000L,2,"return \"\""));
		sList.add(new Statement(200000L,1,"}"));
		sList.add(new Statement(201000L,1,""));
		sList.add(new Statement(202000L,1,"if end>length{"));
		sList.add(new Statement(203000L,2,"end = length"));
		sList.add(new Statement(204000L,1,"}"));
		sList.add(new Statement(205000L,0,""));
		sList.add(new Statement(206000L,1,"var substring = \"\""));
		sList.add(new Statement(207000L,1,"for i := start; i < end; i++ {"));
		sList.add(new Statement(208000L,2,"substring += string(r[i])"));
		sList.add(new Statement(209000L,1,"}"));
		sList.add(new Statement(210000L,0,""));
		sList.add(new Statement(211000L,1,"return substring"));
		sList.add(new Statement(212000L,0,"}"));
		sList.add(new Statement(213000L,0,""));
		sList.add(new Statement(214000L,0,"func cut6chars(str string,pos int)  string{"));
		sList.add(new Statement(215000L,1,"return substring(str,pos*6,(pos+1)*6);"));
		sList.add(new Statement(216000L,0,"}"));
		sList.add(new Statement(217000L,0,""));
		sList.add(new Statement(218000L,0,"func count6charsRows(str string) int{"));
		sList.add(new Statement(219000L,1,"var r = []rune(str)"));
		sList.add(new Statement(220000L,1,"length := len(r)"));
		sList.add(new Statement(221000L,1,"rows := int(math.Ceil(float64(length)/6))"));
		sList.add(new Statement(222000L,1,"return rows"));
		sList.add(new Statement(223000L,0,"}"));

		return sList.getContent();
	}

}
